/*
 * Copyright (c) [2021] Zhang Yansen.All rights reserved.
 *
 * vue-tiny-store is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */


import { provide, inject } from 'vue'

const defaultNameSpace = '@default'

export function useModel (key, namespace = defaultNameSpace) {
  const state = inject(`${namespace}/${key}`)
  return state
}

export default function createStore (initialState = {}) {
  let stateTree = {}

  const init = (app, options) => {
    let initVals = {}
    const namespace = defaultNameSpace

    Object.keys(initialState).forEach(key => {
      const hook = initialState[key]
      const val = typeof hook === 'function' ? hook() : hook

      initVals[key] = val
      app.provide(`${namespace}/${key}`, val)
    })

    stateTree[namespace] = initVals
  }

  const addModel = (key, val, namespace = defaultNameSpace) => {
    const origin = stateTree[namespace] || {}
    stateTree[namespace] = {
      ...origin,
      [key]: val,
    }

    provide(`${namespace}/${key}`, val)
  }

  const getState = (key, namespace = defaultNameSpace) => {
    const state = stateTree[namespace] || {}
    return state[key]
  }

  const install = (app, options) => {
    init(app, options)
  }

  return {
    install,
    addModel,
    getState
  }
}
